#include "UdpReceiver.h"
#include "LidarProcesser.h"

#include <QObject>
#include <QUdpSocket>

UdpReceiver::UdpReceiver(std::vector<std::string> ports, QObject *parent) : QObject(parent)
{
    for (std::string &port_str : ports)
    {
        int port = std::stoi(port_str);
        ports_.push_back(port);
        QUdpSocket *socket = new QUdpSocket(this);
        if (!socket->bind(QHostAddress::Any, port))
        {
            delete socket;
            continue;
        }
        connect(socket, &QUdpSocket::readyRead, this, &UdpReceiver::processPendingDatagrams);
        sockets_.append(socket);
    }
}

void UdpReceiver::startListening(quint16 port)
{
    udpSocket->bind(QHostAddress::Any, port);
}

void UdpReceiver::stopListening()
{
    udpSocket->close();
}

void UdpReceiver::processPendingDatagrams()
{

    for (QUdpSocket *socket : sockets_)
    {
        while (socket->hasPendingDatagrams())
        {
            QByteArray datagram;
            datagram.resize(socket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

            if (pManager_ == nullptr)
                return;

            auto *pManager = static_cast<LidarListener *>(pManager_);
            try
            {
                //auto pEntry = static_cast<LidarListenerEX *>(pManager->dataListener());
                pManager->ProcessData(datagram);
            }
            catch (const char *s)
            {
            }

            // auto *pManager = static_cast<LidarProcesser *>(pManager_);
            // for (auto &entry : pManager->dataListeners())
            // {
            //     if (entry.first == socket->localPort())
            //     {
            //         try
            //         {
            //             auto pEntry = static_cast<LidarListener *>(entry.second);
            //             pEntry->ProcessData(datagram);
            //         }
            //         catch (const char *s)
            //         {
            //             qDebug() << s;
            //         }
            //         break;
            //     }
            // }
        }
    }
}

void UdpReceiver::subscribe(void *pManager)
{
    pManager_ = pManager;
}

void UdpReceiver::unsubscribe(void *pManager)
{
}
